import java.math.*;
import java.awt.*;
import java.awt.event.*;

import javax.media.opengl.*;
import javax.media.opengl.glu.*;
import javax.swing.JFrame;

import com.jogamp.common.nio.Buffers;

import java.nio.FloatBuffer;
import java.nio.IntBuffer;

public class Sphere extends Shape {

	
	//Sphere Specific Values
	protected float[] texcoords;
	protected FloatBuffer tBuf;
	protected int rings;
	protected int sectors;
	
	public Sphere(float radius, int rings, int sectors){
		centerX = 0;
		centerY = 0;
		centerZ = 0;
		this.rings = rings;
		this.sectors = sectors;
		scale = radius;
		color = 0;
	}
	

	
	public void draw(GL2 gl){
		
		float R = 1.0f/(float)(rings-1);
        float S = 1.0f/(float)(sectors-1);
        int r, s;
        vert = new float[rings * sectors * 3];
        normal = new float[rings * sectors * 3];
        texcoords = new float[rings * sectors * 3];
        
        int v = 0;
        int n = 0;
        int t = 0;
        
        for(r = 0; r < rings; r++){
        	for(s = 0; s < sectors; s++){
        		 float y = (float)Math.sin(-(Math.PI)/2 + Math.PI * r * R);
        		 float x = (float)(Math.cos(2*Math.PI * s * S) * Math.sin(Math.PI * r * R));
        		 float z = (float)(Math.sin(2*Math.PI * s * S) * Math.sin(Math.PI * r * R));
        		 
        		 vert[v] = x*scale;
        		 v++;
        		 vert[v] = y*scale;
        		 v++;
        		 vert[v] = z*scale;
        		 v++;
        		 
        		 normal[n] = -x;
        		 n++;
        		 normal[n] = -y;
        		 n++;
        		 normal[n] = -z;
        		 n++;
        		 
        		 texcoords[t] = s*S;
        		 t++;
        		 texcoords[t] = r*R;
        		 t++;
        	}
        }
        
        indi = new int[rings * sectors * 4];
        int j = 0;
        
        for(r = 0; r < rings-1; r++){
        	for(s = 0; s < sectors-1; s++){
        		indi[j] = (r * sectors) + s;
        		j++;
        		indi[j] = (r * sectors) + s + 1;
        		j++;
        		indi[j] = ((r + 1) * sectors) + s + 1;
        		j++;
        		indi[j] = ((r + 1) * sectors) + s;
        		j++;
        	}
        }
        
        vert = performTransform(vert, false);
		
		vBuf = Buffers.newDirectFloatBuffer(vert.length);
		vBuf.put(vert);
		vBuf.rewind();
		nBuf = Buffers.newDirectFloatBuffer(normal.length);
		nBuf.put(normal);
		nBuf.rewind();
		tBuf = Buffers.newDirectFloatBuffer(texcoords.length);
		tBuf.put(texcoords);
		tBuf.rewind();
		iBuf = Buffers.newDirectIntBuffer(indi.length);
		iBuf.put(indi);
		iBuf.rewind();
		
		gl.glMatrixMode(GL2.GL_MODELVIEW);
		gl.glPushMatrix();

		gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
		gl.glEnableClientState(GL2.GL_NORMAL_ARRAY);
		gl.glEnableClientState(GL2.GL_TEXTURE_COORD_ARRAY);

		gl.glVertexPointer(3, GL2.GL_FLOAT, 0, vBuf);
		gl.glNormalPointer(GL2.GL_FLOAT, 0, nBuf);
		gl.glTexCoordPointer(2, GL2.GL_FLOAT, 0, tBuf);
		gl.glColor3f(1.0f, color, 0.0f); // Red
		gl.glDrawElements(GL2.GL_QUADS, indi.length, GL2.GL_UNSIGNED_INT, iBuf);
		gl.glPopMatrix();
		
		gl.glDisableClientState(GL2.GL_VERTEX_ARRAY);
		gl.glDisableClientState(GL2.GL_NORMAL_ARRAY);
		gl.glDisableClientState(GL2.GL_TEXTURE_COORD_ARRAY);
	}
}
